package worker

import (
	"imooc.com/crawler/engine"
	"imooc.com/crawler_distrilbuted/config"
	"imooc.com/crawler/zhenai/parser"
	"github.com/pkg/errors"
	"fmt"
	"log"
)

type SerializedParser struct {
	Name string
	Args interface{}
}

type Request struct {
	Url string
	Parser SerializedParser
}

func SerializeRequest(r engine.Request) Request  {
	name, args := r.Parser.Serialize()
	return Request{
		Url: r.Url,
		Parser: SerializedParser{
			Name: name,
			Args: args,
		},
	}
}

func DeserializeRequest(r Request) (engine.Request, error)  {
	parser, err := deserializeParser(r.Parser)
	if err != nil {
		return engine.Request{},err
	}
	return engine.Request{
		Url:r.Url,
		Parser: parser,
	},nil
}

func deserializeParser(p SerializedParser) (engine.Parser,error)  {
	switch p.Name {
	case config.ParseCityList:
		return engine.NewFuncParser(
			parser.ParseCityList,
			config.ParseCityList), nil
	case config.ParseCity:
		return engine.NewFuncParser(
			parser.ParseCity,
			config.ParseCity), nil
	case config.ParseProfile:
		if name,ok := p.Args.(string);ok {
			return parser.NewParseProfile(name), nil
		}
		return nil,fmt.Errorf("invalid args: %v", p.Args)
	case config.NilParser:
		return engine.NilParser{}, nil
	default:
		return nil, errors.New("Unkown Parser name")
	}

}

type ParseResult struct {
	Items []engine.Item
	Requests []Request
}

func SerializeResult(r engine.ParseResult)ParseResult  {
	result := ParseResult{
		Items: r.Items,
	}

	for _, req := range r.Request {
		result.Requests = append(result.Requests,
			SerializeRequest(req))
	}

	return result
}

func DeserializeResult(r ParseResult)engine.ParseResult  {
	result := engine.ParseResult{
		Items: r.Items,
	}
	for _,req := range r.Requests{
		enginReq, err:= DeserializeRequest(req)
		if err != nil {
			log.Printf("error deserializing request: %v", err)
			continue
		}
		result.Request = append(result.Request, enginReq)
	}

	return  result
}



